package com.qb.baselibrary.basekotlin

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil.setContentView
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.ToastUtils
import com.gyf.immersionbar.ImmersionBar
import com.gyf.immersionbar.ktx.immersionBar
import com.qb.baselibrary.basekotlin.app.MVVMLin
import com.qb.baselibrary.basekotlin.event.Message
import com.qb.baselibrary.R
import com.qb.baselibrary.utils.widget.dialog.MProgressDialog
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

abstract class BaseActivity <VM : BaseViewModel,DB:ViewBinding> : AppCompatActivity() {
    protected lateinit var viewModel: VM
    protected  lateinit var mBinding:DB
    private var mDialog : MProgressDialog?=null
    protected var mContext :Context?=null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mContext = this
        initViewDataBinding()
        lifecycle.addObserver(viewModel)
        //注册 UI事件
        registorDefUIChange()
        initData()
        initView(savedInstanceState)


    }
    open fun layoutId(): Int = 0
    abstract fun initView(savedInstanceState: Bundle?)
    abstract fun initData()

    /**
     * DataBinding or ViewBinding
     */
    private fun initViewDataBinding() {
        val type = javaClass.genericSuperclass
        if (type is ParameterizedType) {
            val cls = type.actualTypeArguments[1] as Class<*>
            when {
                //项目不使用dataBinding注释掉不要了
//                ViewDataBinding::class.java.isAssignableFrom(cls) && cls != ViewDataBinding::class.java -> {
//                    if (layoutId() == 0) throw IllegalArgumentException("Using DataBinding requires overriding method layoutId")
//                    mBinding = setContentView<ViewDataBinding>(this,layoutId()) as DB
//                    (mBinding as ViewDataBinding).lifecycleOwner = this
//                }
                ViewBinding::class.java.isAssignableFrom(cls) && cls != ViewBinding::class.java -> {
                    cls.getDeclaredMethod("inflate", LayoutInflater::class.java).let {
                        @Suppress("UNCHECKED_CAST")
                        mBinding = it.invoke(null, layoutInflater) as DB
                        setContentView(mBinding.root)
                    }
                }
                else -> {
                    if (layoutId() == 0) throw IllegalArgumentException("If you don't use ViewBinding, you need to override method layoutId")
                    setContentView(layoutId())
                }
            }
            createViewModel(type.actualTypeArguments[0])
        } else throw IllegalArgumentException("Generic error")
    }


    private fun registorDefUIChange() {
        viewModel.defUI.showDialog.observe(this, observer = Observer{
            showLoading()
        })
        viewModel.defUI.dismissDialog.observe(this, observer= Observer{
            dismissLoading()
        })
        viewModel.defUI.toastEvent.observe(this, observer= Observer{
            ToastUtils.showShort(it)
        })
        viewModel.defUI.msgEvent.observe(this, observer = Observer{
            handleEvent(it)
        })
    }
    open fun handleEvent(msg: Message) {}

    /**
     * 打开等待框
     */
//    private fun showLoading() {
//        (dialog ?: MaterialDialog(this)
//                .cancelable(false)
//                .cornerRadius(8f)
//                .customView(R.layout.kotlin_custom_dialog, noVerticalPadding = true)
//                .lifecycleOwner(this)
//                .maxWidth(R.dimen.dp_120)
//                .also {
//                    dialog = it
//                })
//                .show()
//    }
//    private fun dismissLoading() {
//        dialog?.run { if (isShowing) dismiss() }
//    }
    //当前通用的 尽量不要单独调用。如果实在需要
    protected fun showLoading(){
        when (mDialog) {
            null -> mDialog = MProgressDialog(mContext)
        }
        mDialog?.showDialog()
    }
    protected fun dismissLoading(){
        mDialog?.run { if (isShowing) dismiss() }
    }

    /**
     * 创建 ViewModel
     */
    @Suppress("UNCHECKED_CAST")
    private fun createViewModel(type: Type) {
        val tClass = type as? Class<VM> ?: BaseViewModel::class.java
        viewModel = ViewModelProvider(viewModelStore, defaultViewModelProviderFactory)
                .get(tClass) as VM
    }

    override fun getDefaultViewModelProviderFactory(): ViewModelProvider.Factory {
        return MVVMLin.getConfig().viewModelFactory() ?: super.getDefaultViewModelProviderFactory()
    }

    /**
     * 处理沉浸式
     */
    protected open fun setImmersionBar(view:View?) {
        ImmersionBar.with(this).init()
        immersionBar {
            mContext?.let {
                statusBarDarkFont(true)
                navigationBarColorInt(it.resources.getColor(R.color.white))
            }
        }
        view?.let{
            setTitleMarginTop(it)
        }
    }

    /**
     * 沉浸式处理距离顶部距离
     */
    protected open fun setTitleMarginTop(view:View){
        val layoutParams: ViewGroup.MarginLayoutParams = view.layoutParams as  ViewGroup.MarginLayoutParams
        layoutParams.topMargin = BarUtils.getStatusBarHeight()
        view.layoutParams = layoutParams
    }
}